package socks

import (
	"errors"
	"fmt"
	"gitee.com/simple-set/simple.io/src/event"
	"gitee.com/simple-set/simple.io/src/process/codec"
)

// Handshake socks握手对象
type Handshake struct {
	version   Version        // 协议版本
	nmethods  byte           // 支持认证的数量
	authTypes []AuthType     // 支持认证的方式
	buff      *codec.ByteBuf // 网络IO缓冲区
	session   *event.Session
}

// NewHandshake 构造函数
func NewHandshake(readBuff *codec.ByteBuf) *Handshake {
	return &Handshake{buff: readBuff}
}

func (h *Handshake) Session() *event.Session {
	return h.session
}

// AddAuthType 添加认证类型
func (h *Handshake) AddAuthType(authType AuthType) {
	if h.authTypes == nil {
		h.authTypes = make([]AuthType, 0)
	}
	h.authTypes = append(h.authTypes, authType)
}

// AuthTypes 获取认证类型
func (h *Handshake) AuthTypes() []AuthType {
	return h.authTypes
}

// Decoder 握手解码
func (h *Handshake) Decoder() error {
	if readByte, err := h.buff.ReadByte(); err != nil {
		return err
	} else {
		h.version = Version(readByte)
	}
	if h.version != V5 {
		return fmt.Errorf("%d version not supported", h.version)
	}

	if readByte, err := h.buff.ReadByte(); err != nil {
		return err
	} else {
		h.nmethods = readByte
	}

	bytes := make([]byte, h.nmethods)
	if n, err := h.buff.Read(bytes); err != nil {
		return err
	} else if n != int(h.nmethods) {
		return errors.New("wrong number of methods")
	}
	for _, b := range bytes {
		h.AddAuthType(AuthType(b))
	}
	return nil
}
